﻿
using Module.FlowChart.Model;
using Module.FlowChart.RunAble.Code.View;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
using static Debugger;

namespace Module.FlowChart.RunAble.Code.Runner
{

    internal enum RunState
    {
        NotRunning,

        ToEnd,
        //ignore call
        NextIgnore,
        //into call
        NextInto,
        //wait for click next step
        WaitForContinue,
        //wait for stop
        WaitStop,
        //wait for io
        WaitForIO,

    }
    internal enum TokenType
    {
        Non,
        Num,
        NumArray,
        Operator,
        Identifier,
        KeyWord,
    }

    internal class Var
    {
        private VarType _type;

        public VarType Type
        {
            get => _type;
            set
            {
                _type = value;
                if (_type == VarType.Arr)
                {
                    Vals = new Dictionary<int, Var>();
                }
                else
                {
                    Vals = null;
                }
            }
        }
        public double Val;
        public Dictionary<int, Var> Vals;
        public bool BoolValue => Val != 0;

        public enum VarType
        {
            Normal, Arr
        }

        public override string ToString()
        {
            if (_type == VarType.Normal)
            {
                return Val.ToString();
            }
            else if (_type == VarType.Arr)
            {
                string s = "{";
                foreach (var val in Vals)
                {
                    s += val.Key + ":" + val.Value.ToString();
                }
                s += "}";
                return s;
            }
            return base.ToString();
        }
        public string TypeName()
        {
            if (_type == VarType.Normal)
            {
                return "值";
            }
            else if (_type == VarType.Arr)
            {
                return "数组";
            }
            return "Unknown";
        }
    }
    internal class RunningContext
    {

        public RunningContext Father = null;
        public RunningContext Child = null;
        public Dictionary<string, Var> vars = new Dictionary<string, Var>();

        public string Name;
        public int CurrentNode;
        public bool FuncReturn;
        public int Depth;

        public RunningContext(string name, int depth = 0)
        {
            Name = name;
            Depth = depth;
        }

        public RunningContext CreatChild(string name, int depth)
        {
            RunningContext c = new RunningContext(name, depth);
            c.Father = this;
            this.Child = c;
            return c;
        }
        /// <summary>
        /// 获取一个变量值
        /// </summary>
        /// <param name="varname">变量名称</param>
        /// <param name="val">变量值</param>
        /// <returns>成功获取？</returns>
        public ErrorType TryGetValue(string varname, out double val)
        {
            if (vars.ContainsKey(varname))
            {
                var v = vars[varname];
                if (v.Type == Var.VarType.Normal)
                {
                    val = v.Val;
                    return ErrorType.Non;
                }
                else
                {
                    val = 0;
                    return ErrorType.ThisIsArr;
                }
            }
            else
            {

                val = 0;
                return ErrorType.NoThisVar;
            }
        }
        /// <summary>
        /// 获取一个变量值
        /// </summary>
        /// <param name="varname">变量名称</param>
        /// <param name="index">数组下标</param>
        /// <param name="val">变量值</param>
        /// <returns>成功获取？</returns>
        public ErrorType TryGetValue(string varname, double index, out double val)
        {
            return TryGetValue(varname, new double[] { index }, out val);
        }
        /// <summary>
        /// 获取一个变量值
        /// </summary>
        /// <returns>成功获取？</returns>
        public ErrorType TryGetValue(string varname, double[] indexs, out double val)
        {
            val = 0;
            if (!vars.ContainsKey(varname))
                return ErrorType.NoThisVar;
            var v = vars[varname];
            if (v.Type == Var.VarType.Normal)
                return ErrorType.ThisIsNotArr;
            foreach (double index in indexs)
            {
                if (v.Type == Var.VarType.Normal)
                    return ErrorType.IndexNumError;
                if ((int)index < 0)
                    return ErrorType.IndexError;
                v = v.Vals[(int)index];
            }
            if (v.Type == Var.VarType.Arr)
                return ErrorType.IndexNumError;
            val = v.Val;
            return ErrorType.Non;
        }
        /// <summary>
        /// 设置一个变量值
        /// </summary>
        /// <param name="varname">变量名称</param>
        /// <param name="val">值</param>
        /// <returns>成功？</returns>
        public ErrorType SetValue(string varname, double val)
        {
            Var v;
            if (vars.ContainsKey(varname))
                v = vars[varname];
            else
            {
                v = new Var();
                vars.Add(varname, v);
            }
            v.Type = Var.VarType.Normal;
            v.Val = val;
            return ErrorType.Non;
        }
        /// <summary>
        /// 设置一个变量值
        /// </summary>
        /// <param name="varname">变量名称</param>
        /// <param name="index">数组下标</param>
        /// <param name="val">值</param>
        /// <returns>成功？</returns>
        public ErrorType SetValue(string varname, double index, double val)
        {
            return SetValue(varname, new double[] { index }, val);
        }
        /// <summary>
        /// 设置一个变量值
        /// </summary>
        /// <returns>成功？</returns>
        public ErrorType SetValue(string varname, double[] indexs, double val)
        {
            Var v;
            if (!vars.ContainsKey(varname))
                (v = vars[varname] = new Var()).Type = Var.VarType.Arr;
            else
                v = vars[varname];
            foreach (int index in indexs)
            {
                if (index < 0)
                    return ErrorType.IndexError;
                if (!v.Vals.ContainsKey(index))
                    (v = v.Vals[index] = new Var()).Type = Var.VarType.Arr;
                else
                {
                    v = v.Vals[index];
                    if (v.Type != Var.VarType.Arr)
                        //warning 提示强制修改对象类型
                        v.Type = Var.VarType.Arr;
                }
            }
            v.Type = Var.VarType.Normal;
            v.Val = val;
            return ErrorType.Non;
        }
        public ErrorType SetValue(string varname, Var v)
        {
            vars[varname] = v;
            return ErrorType.Non;
        }
        public enum ErrorType
        {
            Non,
            IndexError,
            NoThisVar,
            ThisIsArr,
            ThisIsNotArr,
            IndexNumError,
        }
    }
    internal class RunResult
    {
        //static public RunResult Empty = new RunResult();

        public bool IsError;
        public bool WaitForIO;
        public string ErrorInfo;
        public Var Value;
        public RunResult()
        {

        }
        public RunResult(string ErrorInfo)
        {
            IsError = true;
            this.ErrorInfo = ErrorInfo;
            WaitForIO = false;
        }
        public RunResult(bool waitforio)
        {
            Assert(waitforio == true);
            IsError = !waitforio;
            this.ErrorInfo = "";
            WaitForIO = waitforio;
        }
        public RunResult(Var var)
        {
            Value = var; ErrorInfo = ""; IsError = false;
        }
    }
    internal class Token
    {
        public int Line;
        public int Pos;
        public TokenType Type;
        public double Dvalue;
        public double[] Darr;
        public string Name;

        static public Token Num(int line, int pos, double v)
        {
            return new Token() { Line = line, Pos = pos, Type = TokenType.Num, Dvalue = v, Name = v.ToString() };
        }
        static public Token Operator(int line, int pos, string op)
        {
            return new Token() { Line = line, Pos = pos, Type = TokenType.Operator, Name = op };
        }
        static public Token Arr(int line, int pos, List<double> vs)
        {
            return new Token() { Line = line, Pos = pos, Darr = vs.ToArray(), Type = TokenType.NumArray, Name = "arr" + vs.Count };
        }
        static public Token Identifier(int line, int pos, string str)
        {
            return new Token() { Line = line, Pos = pos, Type = TokenType.Identifier, Name = str };
        }
        static public Token KeyWord(int line, int pos, string str)
        {
            return new Token() { Line = line, Pos = pos, Type = TokenType.KeyWord, Name = str };
        }
        static public Token Empty()
        {
            return new Token() { Line = 0, Pos = 0, Type = TokenType.Non };
        }

        public override string ToString()
        {
            return Name;
        }
    }
    internal class TokenCollection
    {
        Token[] tokens;
        int start;
        int offset;
        int end;

        public int Count => end - start + 1;
        public TokenCollection(Token[] tokens, int start = 0, int end = -1)
        {
            Assert(start >= 0 && start < tokens.Length);
            Assert(end == -1 || (end >= start && end < tokens.Length));
            this.tokens = tokens;
            this.offset = this.start = start;
            this.end = end == -1 ? tokens.Length - 1 : end;
        }

        public Token Next()
        {
            if (offset > end)
                return Token.Empty();
            else
                return tokens[offset++];
        }
        public Token Peek()
        {
            if (offset > end)
                return Token.Empty();
            else
                return tokens[offset];
        }
        public Token Back()
        {
            Assert(offset > start);
            return tokens[--offset];
        }
    }
    internal class Exp
    {

        static Dictionary<string, Exp> exps = new Dictionary<string, Exp>();
        static public void ClearExps() { exps.Clear(); }
        static public Exp GetExp(string expstr, int line, int startpos, out RunResult res)
        {
            if (exps.ContainsKey(expstr))
            {
                res = new RunResult();
                return exps[expstr];
            }
            else
            {
                try
                {
                    Exp t = new Exp();
                    t.expstr = expstr;
                    List<Token> tokens = new List<Token>();
                    char[] arr = (expstr + "e").ToCharArray();
                    arr[arr.Length - 1] = '\0';
                    int ptr = 0; char c;
                    c = arr[ptr];
                    //todo
                    while (c != '\0')
                    {
                        while (c == ' ')
                            c = arr[++ptr];
                        if (IsNum(c))
                        {
                            tokens.Add(Token.Num(line, startpos + tokens.Count, GetNum(arr, ref ptr)));
                            c = arr[ptr];
                        }
                        else if (IsLetter(c) || c == '_')
                        {
                            string s = GetIdentifier(arr, ref ptr);
                            if (s == "true" || s == "false")
                            {
                                tokens.Add(Token.KeyWord(line, startpos + tokens.Count, s));
                            }
                            else
                            {
                                tokens.Add(Token.Identifier(line, startpos + tokens.Count, s));
                            }
                            c = arr[ptr];
                        }
                        else
                        {
                            if (c == '{')
                            {
                                List<double> varr = new List<double>();
                                c = arr[++ptr];
                                while (true)
                                {
                                    while (c == ' ')
                                        c = arr[++ptr];
                                    if (IsNum(c))
                                    {
                                        varr.Add(GetNum(arr, ref ptr));
                                        c = arr[ptr];
                                        while (c == ' ')
                                            c = arr[++ptr];
                                        if (c == '}')
                                        {
                                            tokens.Add(Token.Arr(line, startpos + tokens.Count, varr));
                                            c = arr[++ptr];
                                            break;
                                        }
                                        else if (c == ',')
                                        {
                                            c = arr[++ptr];

                                        }
                                        else
                                        {
                                            res = new RunResult("请输入正确的赋值");
                                            return null;
                                        }
                                    }
                                }
                            }
                            else if ("+-*/%()[],".Contains(c.ToString()))
                            {
                                tokens.Add(Token.Operator(line, startpos + tokens.Count, c.ToString()));
                                c = arr[++ptr];
                            }
                            else if ("=><".Contains(c.ToString()))
                            {
                                //= == > < >= <= <>
                                if (c == '=')
                                {
                                    c = arr[++ptr];
                                    if (c == '=')
                                    {//==
                                        tokens.Add(Token.Operator(line, startpos + tokens.Count, "=="));
                                        c = arr[++ptr];
                                    }
                                    else
                                    {//=
                                        tokens.Add(Token.Operator(line, startpos + tokens.Count, "="));
                                    }
                                }
                                else if (c == '>')
                                {
                                    c = arr[++ptr];
                                    if (c == '=')
                                    {//>=
                                        tokens.Add(Token.Operator(line, startpos + tokens.Count, ">="));
                                        c = arr[++ptr];
                                    }
                                    else
                                    {//>
                                        tokens.Add(Token.Operator(line, startpos + tokens.Count, ">"));
                                    }
                                }
                                else if (c == '<')
                                {
                                    c = arr[++ptr];
                                    if (c == '=')
                                    {//<=
                                        tokens.Add(Token.Operator(line, startpos + tokens.Count, "<="));
                                        c = arr[++ptr];
                                    }
                                    else if (c == '>')
                                    {//<>
                                        tokens.Add(Token.Operator(line, startpos + tokens.Count, "<>"));
                                        c = arr[++ptr];
                                    }
                                    else
                                    {//<
                                        tokens.Add(Token.Operator(line, startpos + tokens.Count, "<"));
                                    }
                                }
                            }//todo & && | ||

                            else
                            {
                                throw new Exception("未知符号");
                            }
                        }
                    }
                    t.Tokens = tokens.ToArray();
                    exps[expstr] = t;
                    res = new RunResult();
                    return t;
                }
                catch (Exception e)
                {
                    res = new RunResult(e.Message);
                    return null;
                    throw;
                }

            }
        }
        static bool IsNum(char c)
        {
            return c >= '0' && c <= '9';
        }
        static double GetNum(char[] arr, ref int ptr)
        {
            bool find = false; int start = ptr;
            while (IsNum(arr[ptr]) || (arr[ptr] == '.' && !find))
            {
                if (arr[ptr] == '.')
                {
                    find = true;
                }
                ptr++;
            }
            return double.Parse(new string(arr, start, ptr - start));
        }
        static bool IsLetter(char c)
        {
            return c >= 'a' && c <= 'z' || c >= 'A' && c <= 'Z';
        }
        static string GetIdentifier(char[] arr, ref int ptr)
        {
            int start = ptr;
            ptr++;
            while (IsNum(arr[ptr]) || IsLetter(arr[ptr]) || arr[ptr] == '_')
            {
                ptr++;
            }
            return new string(arr, start, ptr - start);
        }

        string expstr;
        Token[] Tokens;

        public TokenCollection GetTokens(int offset = 0, int end = -1)
        {
            return new TokenCollection(Tokens, offset, end);
        }

        Exp() { }



    }
    internal class RunningStack
    {
        public List<RunningContext> RS = new List<RunningContext>();
        int Top = -1;

        public string Name { get => RS[Top].Name; }
        public int CurrentNode { get => RS == null ? 0 : RS[Top].CurrentNode; set => RS[Top].CurrentNode = value; }
        public RunningContext Context { get => RS[Top]; set => RS[Top] = value; }
        public bool FuncReturn { get => RS[Top].FuncReturn; set => RS[Top].FuncReturn = value; }
        public RunningContext Root;
        public int Depth => Top + 1;
        public void Init()
        {
            RS.Clear();
            Top = -1;
            Root = null;
        }
        public void Pop()
        {
            Top--;
            if (Depth > 0)
            {
                Context.Child = null;
            }
            if (Depth == 0)
            {
                Root = null;
            }
        }
        public void Push(string name = "")
        {
            if (RS.Count == 0)
            {
                ++Top;
                while (RS.Count <= Top)
                {
                    RS.Add(null);
                }
                RS[Top] = new RunningContext(name);
                Root = Context;
            }
            else
            {
                ++Top;
                while (RS.Count <= Top)
                {
                    RS.Add(null);
                }
                RS[Top] = RS[Top - 1].CreatChild(name, Top);
                RS[Top].Name = name;
            }
        }
    }
    internal class RunnerHandles
    {
        public Func<string, int, FCNode> GetNode;//用于获取节点 页名称，节点id  ;取消对fcdoc的依赖关系
        public Action<double> OutPutValue;//用于输出double
        public Func<double> TryGetInputValue;//获取一个输
        public Func<bool> CanGetInputValue;//获取一个输入 返回是否成功输入
        public Action<string, int> OnRunNode;//当节点正在被执行时 通知界面高亮节点
                                             // public Action DoEvents;//用于维护界面,防止界面卡死
        public Func<string, int> FindFunction;//获取名称为 参数1的开始节点
        public Action<string, string> CMD;
        public Action OnEndRun;
        public IVarShower VarShower;
        public Action OnStartRun;
        internal Action<string, int> OnFunctionReturn;
        internal Action<RunningContext> OnNewFunctionReady;

        public RunnerHandles()
        {
            GetNode = null; OutPutValue = null; TryGetInputValue = null; CanGetInputValue = null;
            OnRunNode = null;/* DoEvents = null;*/ FindFunction = null;
            CMD = null;
        }
    }


    #region 同步基于迭代器
    ////同步，基于迭代器
    //internal class ExpRunner
    //{
    //    public RunningContext Global;
    //    public RunningStack Stack;
    //    public Func<string, RunResult> CallFunction;

    //    public void Init(RunningContext global, RunningStack stack, Func<string, RunResult> caller = null)
    //    {
    //        Global = global;
    //        Stack = stack;
    //        CallFunction = caller;
    //        Exp.ClearExps();
    //    }
    //    public IEnumerator<RunResult> Asg(TokenCollection left, TokenCollection right)
    //    {
    //        Token t = left.Next(); IEnumerator<RunResult> ie; RunResult r = null;
    //        if (t.Type == TokenType.Identifier)
    //        {
    //            string name = t.Name;
    //            t = left.Next();
    //            if (t.Name == "(")
    //            {
    //                throw new Exception();
    //            }
    //            else if (t.Name == "[")
    //            {
    //                List<double> indexs = new List<double>();
    //                while (t.Type == TokenType.Operator && t.Name == "[")
    //                {
    //                    ie = GetValue(left);
    //                    if (ie.MoveNext())
    //                    {
    //                        r = ie.Current;
    //                        while (ie.MoveNext())
    //                        {
    //                            yield return null;
    //                            r = ie.Current;
    //                        }
    //                    }
    //                    indexs.Add(r.Value.Val);
    //                    t = left.Next();
    //                    if (t.Type != TokenType.Operator && t.Name == "]")
    //                        throw new Exception("no ]");
    //                }
    //                ie = GetValue(right);
    //                if (ie.MoveNext())
    //                {
    //                    r = ie.Current;
    //                    while (ie.MoveNext())
    //                    {
    //                        yield return null;
    //                        r = ie.Current;
    //                    }
    //                }
    //                Stack.Context.SetValue(name, indexs.ToArray(), r.Value.Val);
    //                yield return new RunResult(new Var() { Type = Var.VarType.Normal, Val = r.Value.Val });
    //                yield break;
    //            }
    //            else if (t.Type == TokenType.Non)
    //            {
    //                ie = GetValue(right);
    //                if (ie.MoveNext())
    //                {
    //                    r = ie.Current;
    //                    while (ie.MoveNext())
    //                    {
    //                        yield return null;
    //                        r = ie.Current;
    //                    }
    //                }
    //                double v = r.Value.Val;//left.Back();
    //                Stack.Context.SetValue(name, v);
    //                yield return new RunResult(new Var() { Type = Var.VarType.Normal, Val = v });
    //                yield break;
    //            }
    //        }
    //        throw new Exception();
    //    }
    //    public IEnumerator<RunResult> Asg(TokenCollection left, double right)
    //    {
    //        return Asg(left, new TokenCollection(new Token[] { Token.Num(0, 0, right) }));
    //    }
    //    public IEnumerator<RunResult> GetValue(TokenCollection tokens)
    //    {
    //        return P12(tokens);
    //    }
    //    //[] () 
    //    public IEnumerator<RunResult> P1(TokenCollection tokens)
    //    {
    //        Token t = tokens.Next(); IEnumerator<RunResult> ie; RunResult r = null;
    //        if (t.Type == TokenType.Num)
    //        {
    //            yield return new RunResult(new Var() { Val = t.Dvalue });
    //            yield break;
    //        }
    //        //括号
    //        if (t.Type == TokenType.Operator && t.Name == "(")
    //        {
    //            ie = P12(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r = ie.Current;
    //                }
    //            }
    //            t = tokens.Next();
    //            if (t.Type != TokenType.Operator && t.Name == ")")
    //                throw new Exception("no )");
    //            yield return r;
    //            yield break;
    //        }
    //        //
    //        if (t.Type == TokenType.KeyWord)
    //        {
    //            if (t.Name == "true")
    //            {
    //                yield return new RunResult(new Var() { Val = 1 });
    //                yield break;
    //            }
    //            else if (t.Name == "false")
    //            {
    //                yield return new RunResult(new Var() { Val = 1 });
    //                yield break;
    //            }

    //        }
    //        //数组或者函数 或者变量
    //        if (t.Type == TokenType.Identifier)
    //        {
    //            string name = t.Name;
    //            t = tokens.Next();
    //            if (t.Type == TokenType.Operator && t.Name == "(")
    //            {
    //                double v;
    //                //tokens.Next();
    //                CallFunction(name);
    //                Stack.Context.TryGetValue("returns", out v);
    //                if (t.Type == TokenType.Operator && t.Name == ")")
    //                {
    //                    tokens.Next();
    //                    yield return new RunResult(new Var() { Val = v });
    //                    yield break;
    //                }
    //                else
    //                {
    //                    throw new Exception("no )");
    //                }
    //            }
    //            if (t.Type == TokenType.Operator && t.Name == "[")
    //            {
    //                double v;
    //                List<double> indexs = new List<double>();
    //                while (t.Type == TokenType.Operator && t.Name == "[")
    //                {
    //                    ie = GetValue(tokens);
    //                    if (ie.MoveNext())
    //                    {
    //                        r = ie.Current;
    //                        while (ie.MoveNext())
    //                        {
    //                            yield return null;
    //                            r = ie.Current;
    //                        }
    //                    }
    //                    indexs.Add(r.Value.Val);
    //                    t = tokens.Next();
    //                    if (t.Type != TokenType.Operator && t.Name == "]")
    //                        throw new Exception("no ]");
    //                }
    //                Stack.Context.TryGetValue(name, indexs.ToArray(), out v);
    //                yield return new RunResult(new Var() { Val = v });
    //                yield break;
    //            }
    //            else
    //            {
    //                double v; tokens.Back();
    //                Stack.Context.TryGetValue(name, out v);
    //                yield return new RunResult(new Var() { Val = v });
    //                yield break;
    //            }
    //        }
    //        throw new Exception();
    //    }
    //    //负号 //! ~
    //    public IEnumerator<RunResult> P2(TokenCollection tokens)
    //    {
    //        Token t = tokens.Peek(); IEnumerator<RunResult> ie; RunResult r = null;
    //        //负数
    //        if (t.Type == TokenType.Operator && t.Name == "-")
    //        {
    //            tokens.Next();
    //            t = tokens.Peek();
    //            ie = P1(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r = ie.Current;
    //                }
    //            }
    //            r.Value.Val = -r.Value.Val;
    //            yield return r;
    //            yield break;
    //        }


    //        ie = P1(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }
    //        yield return r;
    //        yield break;
    //    }
    //    //*/%
    //    public IEnumerator<RunResult> P3(TokenCollection tokens)
    //    {
    //        RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
    //        ie = P2(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }

    //        Token t = tokens.Peek();
    //        while (t.Type == TokenType.Operator && (t.Name == "*" || t.Name == "/" || t.Name == "%"))
    //        {
    //            string name = t.Name;
    //            tokens.Next();
    //            //
    //            ie = P2(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r2 = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r2 = ie.Current;
    //                }
    //            }

    //            t = tokens.Peek();
    //            if (name == "*")
    //            {
    //                r.Value.Val = r.Value.Val * r2.Value.Val;
    //            }
    //            else if (name == "/")
    //            {
    //                r.Value.Val = r.Value.Val / r2.Value.Val;
    //            }
    //            else
    //            {
    //                r.Value.Val = r.Value.Val % r2.Value.Val;
    //            }

    //        }
    //        yield return r;
    //        yield break;
    //    }
    //    //+-
    //    public IEnumerator<RunResult> P4(TokenCollection tokens)
    //    {
    //        RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
    //        ie = P3(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }

    //        Token t = tokens.Peek();
    //        while (t.Type == TokenType.Operator && (t.Name == "+" || t.Name == "-"))
    //        {
    //            string name = t.Name;
    //            tokens.Next();

    //            ie = P3(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r2 = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r2 = ie.Current;
    //                }
    //            }

    //            t = tokens.Peek();
    //            if (name == "+")
    //            {
    //                r.Value.Val = r.Value.Val + r2.Value.Val;
    //            }
    //            else
    //            {
    //                r.Value.Val = r.Value.Val - r2.Value.Val;
    //            }

    //        }
    //        yield return r;
    //        yield break;
    //    }
    //    //<< >>
    //    public IEnumerator<RunResult> P5(TokenCollection tokens)
    //    {
    //        RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
    //        ie = P4(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }

    //        Token t = tokens.Peek();
    //        while (t.Type == TokenType.Operator && (t.Name == "<<" || t.Name == ">>"))
    //        {
    //            string name = t.Name;
    //            tokens.Next();
    //            //
    //            ie = P4(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r2 = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r2 = ie.Current;
    //                }
    //            }

    //            t = tokens.Peek();
    //            if (name == "<<")
    //            {
    //                r.Value.Val = (int)r.Value.Val << (int)r2.Value.Val;
    //            }
    //            else
    //            {
    //                r.Value.Val = (int)r.Value.Val >> (int)r2.Value.Val;
    //            }

    //        }
    //        yield return r;
    //        yield break;
    //    }
    //    // > >= < <=
    //    public IEnumerator<RunResult> P6(TokenCollection tokens)
    //    {

    //        RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
    //        ie = P5(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }

    //        Token t = tokens.Peek();
    //        while (t.Type == TokenType.Operator && (t.Name == ">" || t.Name == ">=" || t.Name == "<" || t.Name == "<="))
    //        {
    //            string name = t.Name;
    //            tokens.Next();
    //            //
    //            ie = P5(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r2 = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r2 = ie.Current;
    //                }
    //            }

    //            t = tokens.Peek();
    //            if (name == ">")
    //            {
    //                r.Value.Val = (r.Value.Val > r2.Value.Val) ? 1 : 0;
    //            }
    //            else if (name == ">=")
    //            {
    //                r.Value.Val = (r.Value.Val >= r2.Value.Val) ? 1 : 0;
    //            }
    //            else if (name == "<")
    //            {
    //                r.Value.Val = (r.Value.Val < r2.Value.Val) ? 1 : 0;
    //            }
    //            else //( name== ">=")
    //            {
    //                r.Value.Val = (r.Value.Val <= r2.Value.Val) ? 1 : 0;
    //            }
    //        }
    //        yield return r;
    //        yield break;
    //    }
    //    //== <>
    //    public IEnumerator<RunResult> P7(TokenCollection tokens)
    //    {
    //        RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
    //        ie = P6(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }

    //        Token t = tokens.Peek();
    //        while (t.Type == TokenType.Operator && (t.Name == "==" || t.Name == "<>"))
    //        {
    //            string name = t.Name;
    //            tokens.Next();
    //            //
    //            ie = P6(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r2 = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r2 = ie.Current;
    //                }
    //            }

    //            t = tokens.Peek();
    //            if (name == "==")
    //            {
    //                r.Value.Val = (r.Value.Val == r2.Value.Val) ? 1 : 0;
    //            }
    //            else
    //            {
    //                r.Value.Val = (r.Value.Val != r2.Value.Val) ? 1 : 0;
    //            }

    //        }
    //        yield return r;
    //        yield break;
    //    }
    //    //&
    //    public IEnumerator<RunResult> P8(TokenCollection tokens)
    //    {
    //        RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
    //        ie = P7(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }

    //        Token t = tokens.Peek();
    //        while (t.Type == TokenType.Operator && t.Name == "&")
    //        {
    //            string name = t.Name;
    //            tokens.Next();
    //            //
    //            ie = P7(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r2 = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r2 = ie.Current;
    //                }
    //            }

    //            t = tokens.Peek();
    //            r.Value.Val = ((int)r.Value.Val & (int)r2.Value.Val);
    //        }
    //        yield return r;
    //        yield break;
    //    }
    //    //todo ^
    //    public IEnumerator<RunResult> P9(TokenCollection tokens)
    //    {
    //        return P8(tokens);
    //    }
    //    // |
    //    public IEnumerator<RunResult> P10(TokenCollection tokens)
    //    {
    //        RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
    //        ie = P9(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }

    //        Token t = tokens.Peek();
    //        while (t.Type == TokenType.Operator && t.Name == "|")
    //        {
    //            string name = t.Name;
    //            tokens.Next();
    //            //
    //            ie = P9(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r2 = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r2 = ie.Current;
    //                }
    //            }

    //            t = tokens.Peek();
    //            r.Value.Val = ((int)r.Value.Val | (int)r2.Value.Val);
    //        }
    //        yield return r;
    //        yield break;
    //    }
    //    //&& 
    //    public IEnumerator<RunResult> P11(TokenCollection tokens)
    //    {
    //        RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
    //        ie = P10(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }

    //        Token t = tokens.Peek();
    //        while (t.Type == TokenType.Operator && t.Name == "&&")
    //        {
    //            string name = t.Name;
    //            tokens.Next();
    //            //
    //            ie = P10(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r2 = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r2 = ie.Current;
    //                }
    //            }

    //            t = tokens.Peek();
    //            r.Value.Val = (r.Value.BoolValue && r2.Value.BoolValue) ? 1 : 0;
    //        }
    //        yield return r;
    //        yield break;
    //    }
    //    // ||
    //    public IEnumerator<RunResult> P12(TokenCollection tokens)
    //    {
    //        RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
    //        ie = P11(tokens);
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return null;
    //                r = ie.Current;
    //            }
    //        }

    //        Token t = tokens.Peek();
    //        while (t.Type == TokenType.Operator && t.Name == "||")
    //        {
    //            tokens.Next();
    //            //
    //            ie = P11(tokens);
    //            if (ie.MoveNext())
    //            {
    //                r2 = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r2 = ie.Current;
    //                }
    //            }

    //            t = tokens.Peek();
    //            r.Value.Val = (r.Value.BoolValue || r2.Value.BoolValue) ? 1 : 0;
    //        }
    //        yield return r;
    //        yield break;
    //    }
    //}
    //internal class CodeRunner
    //{
    //    public int TimeRunningEvertNode = 100;//ms 表示节点执行的间隔 用于在可视化界面高亮节点
    //    RunnerHandles Handles;

    //    private ExpRunner ExpRunner;
    //    private RunningStack Stack;
    //    private RunningContext Global;
    //    private IEnumerator<bool> IE;

    //    public RunState RunState { get; private set; }
    //    public RunState SubState { get; private set; }
    //    public int StepCount { get; private set; }//当前执行的流程块的个数,防止进入死循环
    //    public bool IsError { get; private set; }

    //    public CodeRunner(RunnerHandles handles)
    //    {
    //        Handles = handles;

    //        ExpRunner = new ExpRunner();
    //        Global = new RunningContext();
    //        Stack = new RunningStack();

    //        RunState = RunState.NotRunning;
    //    }

    //    private void PrintMessage(string s)
    //    {
    //        Handles.CMD("Console", s);
    //    }
    //    private IEnumerator<RunResult> RunOneStep()
    //    {
    //        IEnumerator<RunResult> ie; RunResult r = null;
    //        FCNode current = Handles.GetNode(Stack.Name, Stack.CurrentNode);
    //        StepCount++;
    //        if (current.Type == FCNodeType.IO)
    //        {
    //            if (current.IsOutPut)
    //            {
    //                Exp e = Exp.GetExp(current.IOExp, Stack.CurrentNode, 0, out _);//todo 错误处理
    //                ie = ExpRunner.GetValue(e.GetTokens());
    //                if (ie.MoveNext())
    //                {
    //                    r = ie.Current;
    //                    while (ie.MoveNext())
    //                    {
    //                        yield return null;
    //                        r = ie.Current;
    //                    }
    //                }
    //                Handles.OutPutValue(r.Value.Val);
    //            }
    //            else
    //            {
    //                if (!Handles.CanGetInputValue())
    //                {
    //                    StepCount--;
    //                    SubState = RunState == RunState.WaitForIO ? SubState : RunState;
    //                    RunState = RunState.WaitForIO;
    //                    yield return new RunResult(true);
    //                }

    //                Exp e1 = Exp.GetExp(current.IOExp, Stack.CurrentNode, 0, out _);//todo 错误处理
    //                ie = ExpRunner.Asg(e1.GetTokens(), Handles.TryGetInputValue());
    //                if (ie.MoveNext())
    //                {
    //                    r = ie.Current;
    //                    while (ie.MoveNext())
    //                    {
    //                        yield return null;
    //                        r = ie.Current;
    //                    }
    //                }
    //            }
    //            Stack.CurrentNode = current.Next;
    //            yield break;
    //        }
    //        else if (current.Type == FCNodeType.Assign)
    //        {
    //            Exp e1 = Exp.GetExp(current.LeftExp, Stack.CurrentNode, 0, out _);
    //            Exp e2 = Exp.GetExp(current.RightExp, Stack.CurrentNode, 0, out _);//todo 错误处理
    //            ie = ExpRunner.Asg(e1.GetTokens(), e2.GetTokens());
    //            if (ie.MoveNext())
    //            {
    //                r = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r = ie.Current;
    //                }
    //            }
    //            Stack.CurrentNode = current.Next;
    //            yield break;
    //        }
    //        else if (current.Type == FCNodeType.IF)
    //        {
    //            Exp e1 = Exp.GetExp(current.ConditionExp, Stack.CurrentNode, 0, out _);
    //            ie = ExpRunner.GetValue(e1.GetTokens());
    //            if (ie.MoveNext())
    //            {
    //                r = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r = ie.Current;
    //                }
    //            }
    //            if (r.Value.BoolValue)
    //            {
    //                Stack.CurrentNode = current.TrueNext;
    //            }
    //            else
    //            {
    //                Stack.CurrentNode = current.FalseNext;
    //            }
    //            yield break;
    //        }
    //        else if (current.Type == FCNodeType.Terminal)
    //        {
    //            if (!current.IsStartNode)
    //                Stack.FuncReturn = true;
    //            else
    //                Stack.CurrentNode = current.Next;
    //            yield break;
    //        }
    //        else
    //        {
    //            Assert("未知类型");
    //        }
    //    }
    //    private IEnumerator<RunResult> OnFunctionReturn()
    //    {
    //        IEnumerator<RunResult> ie; RunResult r = null;
    //        FCNode current = Handles.GetNode(Stack.Name, Stack.CurrentNode);
    //        Handles.OnRunNode(Stack.Name, -1);
    //        Stack.CurrentNode = -1;
    //        if (current.ReturnExp == "")
    //        {
    //            Stack.Pop(0);
    //        }
    //        else
    //        {
    //            Exp e1 = Exp.GetExp(current.ReturnExp, Stack.CurrentNode, 0, out _);
    //            ie = ExpRunner.GetValue(e1.GetTokens());
    //            if (ie.MoveNext())
    //            {
    //                r = ie.Current;
    //                while (ie.MoveNext())
    //                {
    //                    yield return null;
    //                    r = ie.Current;
    //                }
    //            }
    //            Stack.Pop(r.Value.Val);
    //        }
    //        if (Stack.Depth == 0)
    //        {
    //            EndRun();
    //        }
    //    }
    //    private void EndRun()
    //    {
    //        RunState = RunState.NotRunning;
    //        Handles.OnEndRun();
    //    }

    //    private IEnumerator<bool> Call(string name)
    //    {
    //        IEnumerator<RunResult> ie; RunResult r;
    //        Stack.Push(name);
    //        Stack.CurrentNode = Handles.FindFunction(name);
    //        while (!IsError && RunState != RunState.WaitStop && !Stack.FuncReturn)
    //        {
    //            Handles.OnRunNode(Stack.Name, Stack.CurrentNode);
    //            if (RunState == RunState.NextInto)
    //            {
    //                yield return true;
    //                ie = RunOneStep();
    //                if (ie.MoveNext())
    //                {
    //                    r = ie.Current;
    //                    while (ie.MoveNext())
    //                    {
    //                        yield return true;
    //                        r = ie.Current;
    //                    }
    //                }
    //            }
    //            else if (RunState == RunState.NextIgnore)
    //            {
    //                RunState = RunState.ToEnd;//预留接口，让赋值节点可以调用函数
    //                yield return true;
    //                ie = RunOneStep();
    //                if (ie.MoveNext())
    //                {
    //                    r = ie.Current;
    //                    while (ie.MoveNext())
    //                    {
    //                        yield return true;
    //                        r = ie.Current;
    //                    }
    //                }
    //                RunState = RunState.NextIgnore;
    //                yield return true;
    //            }
    //            else if (RunState == RunState.ToEnd)
    //            {
    //                Thread.Sleep(300);
    //                ie = RunOneStep();
    //                if (ie.MoveNext())
    //                {
    //                    r = ie.Current;
    //                    yield return true;
    //                    while (ie.MoveNext())
    //                    {
    //                        yield return true;
    //                        r = ie.Current;
    //                    }
    //                }
    //                //yield return true;
    //            }
    //            else if (RunState == RunState.WaitStop)
    //            {
    //                EndRun();
    //                break;
    //            }
    //        }
    //        ie = OnFunctionReturn();
    //        if (ie.MoveNext())
    //        {
    //            r = ie.Current;
    //            while (ie.MoveNext())
    //            {
    //                yield return true;
    //                r = ie.Current;
    //            }
    //        }
    //        yield return false;
    //        //return new RunResult();
    //    }
    //    /// <summary>
    //    /// 开始执行
    //    /// </summary>
    //    /// <param name="name"></param>
    //    private IEnumerator<bool> RunSync(RunState rs, string name = "Main")
    //    {
    //        Assert(rs == RunState.NextInto || rs == RunState.NextIgnore || rs == RunState.ToEnd);
    //        //初始化
    //        RunState = rs;
    //        IsError = false;
    //        StepCount = 0;
    //        Stack.Init();
    //        ExpRunner.Init(Global, Stack, (n) =>
    //        {
    //            return null;


    //        });
    //        // yield return true;
    //        //
    //        IEnumerator<bool> callie = Call(name);
    //        while (callie.MoveNext())
    //        {
    //            yield return true;
    //            if (!callie.Current)
    //                break;
    //        }
    //        yield return false;
    //    }
    //    public void StartSync(RunState rs, string name = "Main")
    //    {
    //        IE = RunSync(rs, name);
    //        IE.MoveNext();
    //    }
    //    public void StopSync()
    //    {
    //        if (RunState == RunState.NotRunning)
    //            throw new Exception("未运行，无法结束");
    //        EndRun();
    //    }
    //    public bool IOInputed()
    //    {
    //        if (RunState == RunState.WaitForIO)
    //        {
    //            RunState = SubState;
    //            IE.MoveNext();
    //            return IE.Current;
    //        }
    //        return false;
    //    }
    //    public bool NextSync(RunState rs)
    //    {
    //        Assert(rs == RunState.NextInto || rs == RunState.NextIgnore || rs == RunState.ToEnd);

    //        if (RunState == RunState.NotRunning)
    //            throw new Exception("只有在运行时才能执行时才能执行");

    //        if (RunState == RunState.WaitForIO)
    //            return true;
    //        RunState = rs;
    //        IE.MoveNext();
    //        return IE.Current;
    //    }
    //}
    #endregion



    //同步，基于await
    internal class ExpRunnerX
    {
        public RunningStack Stack;
        public Func<string, Var[], Task<RunResult>> CallFunction;

        public void Init(RunningStack stack, Func<string, Var[], Task<RunResult>> caller = null)
        {
            Stack = stack;
            CallFunction = caller;
            Exp.ClearExps();
        }
        public async Task<RunResult> Asg(TokenCollection left, TokenCollection right)
        {
            Token t = left.Next(); RunResult r;
            if (t.Type == TokenType.Identifier)
            {
                string name = t.Name;
                t = left.Next();
                if (t.Name == "(")
                {
                    return new RunResult("左值异常");
                }
                else if (t.Name == "[")
                {
                    List<double> indexs = new List<double>();
                    while (t.Type == TokenType.Operator && t.Name == "[")
                    {
                        r = await GetValue(left);
                        indexs.Add(r.Value.Val);
                        t = left.Next();
                        if (t.Type != TokenType.Operator && t.Name == "]")
                            return new RunResult("no ]");
                        t = left.Next();
                    }
                    r = await GetValue(right);
                    if (r.IsError) return r;
                    Stack.Context.SetValue(name, indexs.ToArray(), r.Value.Val);
                    return new RunResult(new Var() { Type = Var.VarType.Normal, Val = r.Value.Val });
                }
                else if (t.Type == TokenType.Non)
                {
                    r = await GetValue(right);
                    if (r.IsError) return r;
                    double v = r.Value.Val;//left.Back();
                    Stack.Context.SetValue(name, v);
                    return new RunResult(new Var() { Type = Var.VarType.Normal, Val = v });
                }
            }
            return new RunResult("左值异常");
        }
        public async Task<RunResult> Asg(TokenCollection left, double right)
        {
            return await Asg(left, new TokenCollection(new Token[] { Token.Num(0, 0, right) }));
        }
        public async Task<RunResult> GetValue(TokenCollection tokens)
        {
            return await P12(tokens);
        }

        public RunResult SetParams(TokenCollection tokens, Var[] vs)
        {
            int i = 0;
            Token t = tokens.Next();
            if (t.Type == TokenType.Non)
                return new RunResult();
            if (t.Type != TokenType.Identifier)
            {
                return new RunResult("not  Identifier");
            }
            Stack.Context.SetValue(t.Name, vs[i++]);
            t = tokens.Next();
            while (t.Type == TokenType.Operator && t.Name == ",")
            {
                t = tokens.Next();
                if (t.Type != TokenType.Identifier)
                {
                    return new RunResult("not  Identifier");
                }
                Stack.Context.SetValue(t.Name, vs[i++]);
                t = tokens.Next();
            }
            tokens.Back();
            return new RunResult();
        }
        //[] () 
        public async Task<RunResult> P1(TokenCollection tokens)
        {
            Token t = tokens.Next(); RunResult r = null;
            if (t.Type == TokenType.Num)
            {
                return new RunResult(new Var() { Val = t.Dvalue });
            }
            //括号
            if (t.Type == TokenType.Operator && t.Name == "(")
            {
                r = await P12(tokens);
                if (r.IsError)
                    return r;
                t = tokens.Next();
                if (t.Type != TokenType.Operator && t.Name == ")")
                    return new RunResult("no )");
                return r;
            }
            //
            if (t.Type == TokenType.KeyWord)
            {
                if (t.Name == "true")
                {
                    return new RunResult(new Var() { Val = 1 });
                }
                else if (t.Name == "false")
                {
                    return new RunResult(new Var() { Val = 1 });
                }

            }
            //数组或者函数 或者变量
            if (t.Type == TokenType.Identifier)
            {
                string name = t.Name;
                t = tokens.Next();
                //函数
                if (t.Type == TokenType.Operator && t.Name == "(")
                {//call
                    t = tokens.Next();
                    if (t.Type == TokenType.Operator && t.Name == ")")
                    {//无参

                        r = await CallFunction(name, null);
                        return r;
                    }
                    else
                    {//多参数
                        tokens.Back();
                        List<Var> vs = new List<Var>();
                        r = await GetValue(tokens);
                        if (r.IsError)
                            return r;
                        vs.Add(r.Value);
                        t = tokens.Next();
                        while (t.Type == TokenType.Operator && t.Name == ",")
                        {
                            r = await GetValue(tokens);
                            if (r.IsError)
                                return r;
                            vs.Add(r.Value);
                            t = tokens.Next();
                        }
                        if (t.Type == TokenType.Operator && t.Name == ")")
                        {
                            r = await CallFunction(name, vs.ToArray());
                            return r;
                        }
                        else
                        {
                            return new RunResult("no )");
                        }
                    }
                }
                //数组
                if (t.Type == TokenType.Operator && t.Name == "[")
                {
                    double v;
                    List<double> indexs = new List<double>();
                    while (t.Type == TokenType.Operator && t.Name == "[")
                    {
                        r = await GetValue(tokens);
                        if (r.IsError)
                            return r;
                        indexs.Add(r.Value.Val);
                        t = tokens.Next();
                        if (!(t.Type == TokenType.Operator && t.Name == "]"))
                            return new RunResult("no ]");
                    }
                    Stack.Context.TryGetValue(name, indexs.ToArray(), out v);
                    return new RunResult(new Var() { Val = v });
                }
                else
                {
                    double v; tokens.Back();
                    Stack.Context.TryGetValue(name, out v);
                    return new RunResult(new Var() { Val = v });
                }
            }
            return new RunResult("取值异常");
        }
        //负号 //! ~
        public async Task<RunResult> P2(TokenCollection tokens)
        {
            Token t = tokens.Peek(); IEnumerator<RunResult> ie; RunResult r = null;
            //负数
            if (t.Type == TokenType.Operator && t.Name == "-")
            {
                tokens.Next();
                t = tokens.Peek();
                r = await P1(tokens);
                if (r.IsError)
                    return r;
                r.Value.Val = -r.Value.Val;
                return r;
            }
            r = await P1(tokens);
            return r;
        }
        //*/%
        public async Task<RunResult> P3(TokenCollection tokens)
        {
            RunResult r = null, r2 = null;
            r = await P2(tokens);
            if (r.IsError)
                return r;
            Token t = tokens.Peek();
            while (t.Type == TokenType.Operator && (t.Name == "*" || t.Name == "/" || t.Name == "%"))
            {
                string name = t.Name;
                tokens.Next();
                //
                r2 = await P2(tokens);
                if (r2.IsError)
                    return r2;
                t = tokens.Peek();
                if (name == "*")
                {
                    r.Value.Val = r.Value.Val * r2.Value.Val;
                }
                else if (name == "/")
                {
                    r.Value.Val = r.Value.Val / r2.Value.Val;
                }
                else
                {
                    r.Value.Val = r.Value.Val % r2.Value.Val;
                }

            }
            return r;
        }
        //+-
        public async Task<RunResult> P4(TokenCollection tokens)
        {
            RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
            r = await P3(tokens);
            if (r.IsError)
                return r;
            Token t = tokens.Peek();
            while (t.Type == TokenType.Operator && (t.Name == "+" || t.Name == "-"))
            {
                string name = t.Name;
                tokens.Next();

                r2 = await P3(tokens);
                if (r2.IsError)
                    return r2;
                t = tokens.Peek();
                if (name == "+")
                {
                    r.Value.Val = r.Value.Val + r2.Value.Val;
                }
                else
                {
                    r.Value.Val = r.Value.Val - r2.Value.Val;
                }

            }
            return r;
        }
        //<< >>
        public async Task<RunResult> P5(TokenCollection tokens)
        {
            RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
            r = await P4(tokens);
            if (r.IsError)
                return r;
            Token t = tokens.Peek();
            while (t.Type == TokenType.Operator && (t.Name == "<<" || t.Name == ">>"))
            {
                string name = t.Name;
                tokens.Next();
                //
                r2 = await P4(tokens);
                if (r2.IsError)
                    return r2;
                t = tokens.Peek();
                if (name == "<<")
                {
                    r.Value.Val = (int)r.Value.Val << (int)r2.Value.Val;
                }
                else
                {
                    r.Value.Val = (int)r.Value.Val >> (int)r2.Value.Val;
                }

            }
            return r;
        }
        // > >= < <=
        public async Task<RunResult> P6(TokenCollection tokens)
        {

            RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
            r = await P5(tokens);
            if (r.IsError)
                return r;
            Token t = tokens.Peek();
            while (t.Type == TokenType.Operator && (t.Name == ">" || t.Name == ">=" || t.Name == "<" || t.Name == "<="))
            {
                string name = t.Name;
                tokens.Next();
                //
                r2 = await P5(tokens);
                if (r2.IsError)
                    return r2;
                t = tokens.Peek();
                if (name == ">")
                {
                    r.Value.Val = (r.Value.Val > r2.Value.Val) ? 1 : 0;
                }
                else if (name == ">=")
                {
                    r.Value.Val = (r.Value.Val >= r2.Value.Val) ? 1 : 0;
                }
                else if (name == "<")
                {
                    r.Value.Val = (r.Value.Val < r2.Value.Val) ? 1 : 0;
                }
                else //( name== ">=")
                {
                    r.Value.Val = (r.Value.Val <= r2.Value.Val) ? 1 : 0;
                }
            }
            return r;
        }
        //== <>
        public async Task<RunResult> P7(TokenCollection tokens)
        {
            RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
            r = await P6(tokens);
            if (r.IsError)
                return r;

            Token t = tokens.Peek();
            while (t.Type == TokenType.Operator && (t.Name == "==" || t.Name == "<>"))
            {
                string name = t.Name;
                tokens.Next();
                //
                r2 = await P6(tokens);
                if (r2.IsError)
                    return r2;
                t = tokens.Peek();
                if (name == "==")
                {
                    r.Value.Val = (r.Value.Val == r2.Value.Val) ? 1 : 0;
                }
                else
                {
                    r.Value.Val = (r.Value.Val != r2.Value.Val) ? 1 : 0;
                }

            }
            return r;
        }
        //&
        public async Task<RunResult> P8(TokenCollection tokens)
        {
            RunResult r = null, r2 = null; IEnumerator<RunResult> ie;
            r = await P7(tokens);
            if (r.IsError)
                return r;
            Token t = tokens.Peek();
            while (t.Type == TokenType.Operator && t.Name == "&")
            {
                string name = t.Name;
                tokens.Next();
                //
                r2 = await P9(tokens);
                if (r2.IsError)
                    return r2;
                t = tokens.Peek();
                r.Value.Val = ((int)r.Value.Val & (int)r2.Value.Val);
            }
            return r;
        }
        //todo ^
        public async Task<RunResult> P9(TokenCollection tokens)
        {
            return await P8(tokens);
        }
        // |
        public async Task<RunResult> P10(TokenCollection tokens)
        {
            RunResult r = null, r2 = null;
            r = await P9(tokens);
            if (r.IsError)
                return r;
            Token t = tokens.Peek();
            while (t.Type == TokenType.Operator && t.Name == "|")
            {
                string name = t.Name;
                tokens.Next();
                //
                r2 = await P9(tokens);
                if (r2.IsError)
                    return r2;
                t = tokens.Peek();
                r.Value.Val = ((int)r.Value.Val | (int)r2.Value.Val);
            }
            return r;
        }
        //&& 
        public async Task<RunResult> P11(TokenCollection tokens)
        {
            RunResult r = null, r2 = null;
            r = await P10(tokens);
            if (r.IsError)
                return r;
            Token t = tokens.Peek();
            while (t.Type == TokenType.Operator && t.Name == "&&")
            {
                string name = t.Name;
                tokens.Next();
                //
                r2 = await P10(tokens);
                if (r2.IsError)
                    return r2;
                t = tokens.Peek();
                r.Value.Val = (r.Value.BoolValue && r2.Value.BoolValue) ? 1 : 0;
            }
            return r;
        }
        // ||
        public async Task<RunResult> P12(TokenCollection tokens)
        {
            RunResult r = null, r2 = null;
            r = await P11(tokens);
            if (r.IsError)
                return r;
            Token t = tokens.Peek();
            while (t.Type == TokenType.Operator && t.Name == "||")
            {
                tokens.Next();
                r2 = await P11(tokens);
                if (r2.IsError)
                    return r2;
                t = tokens.Peek();
                r.Value.Val = (r.Value.BoolValue || r2.Value.BoolValue) ? 1 : 0;
            }
            return r;
        }
    }
    internal class CodeRunnerXLib
    {
        static Dictionary<string, Func<Var[], RunResult>> libfuncs = new Dictionary<string, Func<Var[], RunResult>>();
        static public bool Has(string name)
        {
            return libfuncs.ContainsKey(name);
        }
        static public RunResult Call(string name, Var[] v = null)
        {
            Assert(libfuncs.ContainsKey(name), "没有库函数" + name);
            return libfuncs[name].Invoke(v);
        }

        static CodeRunnerXLib()
        {
            libfuncs.Add("sqrt", (v) =>
            {
                if (v.Length != 1 || v[0].Type != Var.VarType.Normal)
                {
                    return new RunResult("参数错误");
                }
                if (v[0].Val < 0)
                {
                    return new RunResult("参数不能为负");
                }
                var val = Math.Sqrt(v[0].Val);
                return new RunResult(new Var() { Type = Var.VarType.Normal, Val = val }); ;
            });
            libfuncs.Add("abs", (v) =>
            {
                if (v.Length != 1 || v[0].Type != Var.VarType.Normal)
                {
                    return new RunResult("参数错误");
                }
                var val = Math.Abs(v[0].Val);
                return new RunResult(new Var() { Type = Var.VarType.Normal, Val = val }); ;
            });
            libfuncs.Add("sin", (v) =>
            {
                if (v.Length != 1 || v[0].Type != Var.VarType.Normal)
                {
                    return new RunResult("参数错误");
                }

                var val = Math.Sin(v[0].Val);
                return new RunResult(new Var() { Type = Var.VarType.Normal, Val = val }); ;
            });
            libfuncs.Add("cos", (v) =>
            {
                if (v.Length != 1 || v[0].Type != Var.VarType.Normal)
                {
                    return new RunResult("参数错误");
                }

                var val = Math.Cos(v[0].Val);
                return new RunResult(new Var() { Type = Var.VarType.Normal, Val = val }); ;
            });
            libfuncs.Add("tan", (v) =>
            {
                if (v.Length != 1 || v[0].Type != Var.VarType.Normal)
                {
                    return new RunResult("参数错误");
                }

                var val = Math.Tan(v[0].Val);
                return new RunResult(new Var() { Type = Var.VarType.Normal, Val = val });
            });
        }
    }

    internal class CodeRunnerX
    {
        public int TimeRunningEvertNode = 100;//ms 表示节点执行的间隔 用于在可视化界面高亮节点
        RunnerHandles Handles;

        private ExpRunnerX ExpRunner;
        private RunningStack Stack;

        private AutoResetEvent manualReset;
        public RunState RunState { get; private set; }
        /// <summary>
        /// 是否在运行代码 在运行时不应该进行操作以防不同步
        /// </summary>
        public int StepCount { get; private set; }//当前执行的流程块的个数,防止进入死循环
        public bool IsError { get; private set; }

        public CodeRunnerX(RunnerHandles handles)
        {
            Handles = handles;

            ExpRunner = new ExpRunnerX();
            Stack = new RunningStack();

            RunState = RunState.NotRunning;
        }

        private void SetState(RunState rs)
        {
            RunState = RunState == RunState.WaitStop ? RunState : rs;
        }
        private Task WaitUnLock()
        {
            return Task.Run(() => { manualReset.WaitOne(); });
        }
        private async Task DoEvents()
        {
            if (RunState == RunState.WaitStop)
                return;
            if (RunState == RunState.WaitForIO)
            {
                while (!Handles.CanGetInputValue() && RunState != RunState.WaitStop)
                {
                    await WaitUnLock();
                }
                return;
            }


            Handles.OnRunNode(Stack.Name, Stack.CurrentNode);
            if (RunState == RunState.ToEnd)
            {
                //停止一段时间
                Thread.Sleep(TimeRunningEvertNode);
            }
            else if (RunState == RunState.WaitForContinue)
            {
                await WaitUnLock();
            }
            else
            {
                await WaitUnLock();
            }
        }
        private void RunInit()
        {
            IsError = false;
            StepCount = 0;
            Stack.Init();
            ExpRunner.Init(Stack,
                async (n, p) => { return await Call(n, p); }
                );
        }
        private async Task<RunResult> RunOneStep()
        {

            FCNode current = Handles.GetNode(Stack.Name, Stack.CurrentNode);
            StepCount++;
            if (current.Type == FCNodeType.IO)
            {
                RunResult r;
                if (current.IsOutPut)
                {
                    Exp e = Exp.GetExp(current.IOExp, Stack.CurrentNode, 0, out r);//todo 错误处理
                    if (r.IsError)
                        return r;
                    r = await ExpRunner.GetValue(e.GetTokens());
                    if (r.IsError)
                        return r;
                    Handles.OutPutValue(r.Value.Val);
                }
                else
                {
                    var t = RunState;
                    SetState(RunState.WaitForIO);
                    await DoEvents();
                    if (RunState == RunState.WaitStop)
                        return new RunResult("End");
                    Exp e1 = Exp.GetExp(current.IOExp, Stack.CurrentNode, 0, out r);//todo 错误处理
                    if (r.IsError)
                        return r;
                    r = await ExpRunner.Asg(e1.GetTokens(), Handles.TryGetInputValue());
                    if (r.IsError)
                        return r;
                    SetState(t);
                }
                if ((Stack.CurrentNode = current.Next) < 1)
                    return new RunResult("错误的后继节点");
                return r;
            }
            else if (current.Type == FCNodeType.Assign)
            {
                RunResult r;
                Exp e1 = Exp.GetExp(current.LeftExp, Stack.CurrentNode, 0, out r);
                if (r.IsError)
                    return r;
                Exp e2 = Exp.GetExp(current.RightExp, Stack.CurrentNode, 0, out r);//todo 错误处理
                if (r.IsError)
                    return r;
                r = await ExpRunner.Asg(e1.GetTokens(), e2.GetTokens());
                if (r.IsError)
                    return r;
                Stack.CurrentNode = current.Next;
                if ((Stack.CurrentNode = current.Next) < 1)
                    return new RunResult("错误的后继节点");
                return r;
            }
            else if (current.Type == FCNodeType.IF)
            {
                RunResult r;
                Exp e1 = Exp.GetExp(current.ConditionExp, Stack.CurrentNode, 0, out r);
                if (r.IsError)
                    return r;
                r = await ExpRunner.GetValue(e1.GetTokens());
                if (r.IsError)
                    return r;
                if (r.Value.BoolValue)
                {
                    if ((Stack.CurrentNode = current.TrueNext) < 1)
                        return new RunResult("错误的后继节点");
                }
                else
                {
                    if ((Stack.CurrentNode = current.FalseNext) < 1)
                        return new RunResult("错误的后继节点");
                }

                return r;
            }
            else if (current.Type == FCNodeType.Terminal)
            {
                if (!current.IsStartNode)
                {
                    Stack.FuncReturn = true;
                    return new RunResult(); ;
                }
                Stack.CurrentNode = current.Next;
                if ((Stack.CurrentNode = current.Next) < 1)
                    return new RunResult("错误的后继节点");
                return new RunResult(); ;
            }
            else
            {
                Assert("未知类型");
                return new RunResult(); ;
            }

        }
        private async Task<RunResult> OnFunctionReturn()
        {
            RunResult r; string name = Stack.Name;
            var current = Handles.GetNode(name, Stack.CurrentNode);
            Stack.CurrentNode = -1;
            if (current.ReturnExp == "")
            {
                Stack.Pop();
                r = new RunResult(new Var { Type = Var.VarType.Normal, Val = 0 });
                if (r.IsError)
                    return r;
            }
            else
            {
                Exp e1 = Exp.GetExp(current.ReturnExp, Stack.CurrentNode, 0, out r);
                if (r.IsError)
                    return r;
                r = await ExpRunner.GetValue(e1.GetTokens());
                if (r.IsError)
                    return r;
                Stack.Pop();
            }
            Handles.OnFunctionReturn(name, 0);
            return r;
        }
        private void EndRun()
        {
            RunState = RunState.NotRunning;
            Handles.OnEndRun();
        }

        private async Task<RunResult> Call(string name, Var[] v = null)
        {
            if (CodeRunnerXLib.Has(name))
            {
                return CodeRunnerXLib.Call(name, v);
            }
            RunResult r;
            Stack.Push(name);
            Stack.CurrentNode = Handles.FindFunction(name);
            if (v != null)
            {
                var node = Handles.GetNode(name, Stack.CurrentNode);
                Check(node.Type == FCNodeType.Terminal && node.IsStartNode);
                Exp e = Exp.GetExp(node.Params, Stack.CurrentNode, 0, out r);
                if (r.IsError)
                    return r;
                r = ExpRunner.SetParams(e.GetTokens(), v);
                if (r.IsError) return r;
            }
            //添加变量信息
            Handles.OnNewFunctionReady(Stack.Context);
            while (!IsError && RunState != RunState.WaitStop && !Stack.FuncReturn)
            {
                await DoEvents();
                if (RunState == RunState.NextInto)
                {
                    r = await RunOneStep();
                    if (r.IsError)
                        return r;
                    SetState(RunState.WaitForContinue);
                }
                else if (RunState == RunState.NextIgnore)
                {
                    RunState = RunState.ToEnd;//预留接口，让赋值节点可以调用函数
                    r = await RunOneStep();
                    if (r.IsError)
                        return r;
                    SetState(RunState.WaitForContinue);
                }
                else if (RunState == RunState.ToEnd)
                {
                    r = await RunOneStep();
                    if (r.IsError)
                        return r;
                }
                else if (RunState == RunState.WaitStop)
                {
                    return new RunResult("End");
                }
            }
            r = await OnFunctionReturn();
            if (r.IsError)
                return r;
            Handles.VarShower.RemoveLast();
            return r;
        }
        /// <summary>
        /// 开始执行
        /// </summary>
        /// <param name="name"></param>
        public async void StartSync(RunState rs, string name = "Main")
        {
            if (RunState != RunState.NotRunning)
                throw new Exception("只有在没有运行时才能运行");
            Handles.OnStartRun?.Invoke();

            Assert(rs == RunState.NextInto || rs == RunState.NextIgnore || rs == RunState.ToEnd);

            if (manualReset == null)
                manualReset = new AutoResetEvent(false);
            manualReset.Reset();
            RunState = rs;
            RunInit();
            try
            {
                var r = await Call(name);
                if (r.IsError)
                {
                    IsError = true;
                    throw new Exception(r.ErrorInfo);
                }
            }
            catch (Exception e)
            {
                Handles.CMD("Console", "-------" + e.Message + "-------");
            }

            EndRun();
        }
        public void StopSync()
        {
            if (RunState == RunState.NotRunning)
                throw new Exception("未运行，无法结束");
            RunState = RunState.WaitStop;
            manualReset.Set();
        }
        public void NextSync(RunState rs)
        {
            Assert(rs == RunState.NextInto || rs == RunState.NextIgnore || rs == RunState.ToEnd);

            if (RunState == RunState.NotRunning)
                throw new Exception("只有在运行时才能执行时才能执行");

            if (RunState == RunState.WaitForIO)
                return;
            SetState(rs);
            manualReset.Set();
        }
        public void IOInputed()
        {
            if (RunState == RunState.WaitForIO)
            {
                manualReset.Set();
            }
        }
    }

    //异步,基于Thread
    internal class ExpRuunerAsync
    {

    }
    internal class CodeRunnerAsync
    {

    }

}

